#ifndef __PT_LIST_H__
#define __PT_LIST_H__

#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)

struct pt_list_node
{
	struct pt_list_node	*next;
};

typedef struct pt_list_node pt_list_t;

void pt_list_init(struct pt_list_node *l);
void pt_list_append(struct pt_list_node *l, struct pt_list_node *n);

void pt_list_insert(struct pt_list_node *l, struct pt_list_node *n);
struct pt_list_node *pt_list_remove(struct pt_list_node *l, struct pt_list_node *n);	 

#define pt_list_entry(node, type, member)	\
	PT_CONTAINER_OF(node, type, member)

#define pt_list_foreach(node, list)	\
	for ((node) = (list)->next; (node) != PT_NULL; (node) = (node)->next)

struct pt_dlist_node
{
	struct pt_dlist_node	*next;
	struct pt_dlist_node	*prev;
};
typedef struct pt_dlist_node pt_dlist_t;

#define PTGUI_DLIST_HEAD_INIT(name) { &(name), &(name) }
#define PTGUI_DLIST_HEAD(name) \
	struct pt_dlist_node name = PTGUI_DLIST_HEAD_INIT(name)
#define PTGUI_INIT_LIST_HEAD(ptr) do { \
		(ptr)->next = (ptr); (ptr)->prev = (ptr); \
	} while (0)

void pt_dlist_add(struct pt_dlist_node *node, struct pt_dlist_node *head);
void pt_dlist_add_tail(struct pt_dlist_node *node, struct pt_dlist_node *head);
void pt_dlist_del(struct pt_dlist_node *entry);
void pt_dlist_del_init(struct pt_dlist_node *entry);
void pt_dlist_move(struct pt_dlist_node *list, struct pt_dlist_node *head);
void pt_dlist_move_tail(struct pt_dlist_node *list, struct pt_dlist_node *head);
int pt_dlist_empty(const struct pt_dlist_node *head);
int pt_dlist_empty_careful(const struct pt_dlist_node *head);
void pt_dlist_splice(struct pt_dlist_node *list, struct pt_dlist_node *head);
void pt_dlist_splice_init(struct pt_dlist_node *list, struct pt_dlist_node *head);

#define pt_dlist_entry(ptr, type, member) \
	PTGIO_CONTAINER_OF(ptr, type, member)
#define pt_dlist_for_each(pos, head) \
	for (pos = (head)->next; pos != (head); pos = pos->next)
#define pt_dlist_for_each_prev(pos, head) \
	for (pos = (head)->prev; pos != (head); pos = pos->prev)

#define pt_dlist_for_each_safe(pos, n, head) \
	for (pos = (head)->next, n = pos->next; pos != (head); \
	   pos = n, n = pos->next)

struct pt_hlist_head
{
	struct pt_hlist_node	*first;
};

struct pt_hlist_node
{
	struct pt_hlist_node	*next,
							 **pprev;
};
typedef struct pt_hlist_node pt_hlist_t;

#define PTGUI_HLIST_HEAD_INIT { .first = PT_NULL }
#define PTGUI_HLIST_HEAD(name) struct pt_hlist_node name = { .first = PT_NULL }
#define PTGUI_INIT_HLIST_HEAD(ptr) ((ptr)->first = PT_NULL)
#define PTGUI_INIT_HLIST_NODE(ptr) ((ptr)->next = PT_NULL, (ptr)->pprev = PT_NULL)

int pt_hlist_unhashed(const struct pt_hlist_node *h);
int pt_hlist_empty(const struct pt_hlist_head *h);
void __pt_hlist_del(struct pt_hlist_node *n);
void pt_hlist_del(struct pt_hlist_node *n);
void pt_hlist_del_init(struct pt_hlist_node *n);

void pt_hlist_add_head(struct pt_hlist_node *n, struct pt_hlist_head *h);
void pt_hlist_add_before(struct pt_hlist_node *n, struct pt_hlist_node *next);
void pt_hlist_add_after(struct pt_hlist_node *n, struct pt_hlist_node *next);
#define pt_hlist_entry(ptr, type, member) \
	PTGIO_CONTAINER_OF(ptr,type,member)
#define pt_hlist_for_each(pos, head) \
	for (pos = (head)->first; pos != pt_RT_NULL; pos = pos->next)
#define pt_hlist_for_each_safe(pos, n, head) \
	for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
		  pos = n)

#endif	//__PT_LIST_H__
